//-------------------------------------------------------------------
//	Copyright (c) 2010-2012 Zhirnov Andrey
//	This file is part of the "UXGEN" project.
//	See copyright notice in "Engine.h".
//-------------------------------------------------------------------

#ifndef _UX_THREAD_OPERATION_INTERFACE_H
#define _UX_THREAD_OPERATION_INTERFACE_H

#include <Includes.h>

namespace Engine
{
namespace CoreSystems
{

	//
	// Thread Operation Interface
	//

	class IOperation
	{
	public:
		virtual void Do() = 0;
	};



	//
	// Thread Operation with Counter interface
	//

	class IOperationC : public IOperation
	{
	public:
		virtual void SetCounter(int) = 0;
		virtual void Free() = 0;
	};



	//
	// Universal Operation
	//

	class _EXPORT_ CUniOperation : public IOperation
	{
	public:
		typedef void (*PDoOperationProc_t)(void *pParametr);

	protected:
		PDoOperationProc_t	_pProc;
		void			*	_pParametr;

	public:
		CUniOperation(PDoOperationProc_t pProc, void *pParametr):
			_pProc(pProc), _pParametr(pParametr)
		{
			ASSERT( pProc != nullptr );
		}

		virtual ~CUniOperation()
		{}

		virtual void Do()
		{
			if ( _pProc != nullptr )
				_pProc( _pParametr );

			delete this;
		}
	};



	//
	// Universal Operation with synchronization
	//

	class _EXPORT_ CUniOperationSync : public CUniOperation
	{
	protected:
		TEventSync		_sESync;

	public:
		CUniOperationSync(PDoOperationProc_t pProc, void *pParametr):
			CUniOperation(pProc, pParametr)
		{
			_sESync.Create( false, false );
		}

		~CUniOperationSync()
		{
			_sESync.Delete();
		}

		virtual void Do()
		{
			if ( _pProc != nullptr )
				_pProc( _pParametr );

			_sESync.Set();
		}

		bool Sync(uint uTime = -1)
		{
			return _sESync.Wait( uTime );
		}

		void Free()
		{
			delete this;
		}
	};



	//
	// Universal Operation with Counter
	//

	class _EXPORT_ CUniOperationC : public IOperationC
	{
	public:
		typedef void (*PDoOperationProc_t)(void *pParametr);

	protected:
		PDoOperationProc_t	_pProc;
		void			*	_pParametr;
		atomic_int32		_sCounter;

	public:
		CUniOperationC(PDoOperationProc_t pProc, void *pParametr):
			_pProc(pProc), _pParametr(pParametr), _sCounter(0)
		{
			ASSERT( _pProc != nullptr );
		}

		virtual ~CUniOperationC()
		{}

		virtual void SetCounter(int i)
		{
			_sCounter = i;
		}

		virtual void Free()
		{
			delete this;
		}

		virtual void Do()
		{
			if ( _pProc != nullptr )
				_pProc( _pParametr );

			if ( --_sCounter <= 0 )
				delete this;
		}
	};



	//
	// Universal Operation with Counter & with sync
	//

	class _EXPORT_ CUniOperationCS : public CUniOperationC
	{
	public:
		TEventSync	_sEvent;

	public:
		CUniOperationCS(PDoOperationProc_t pProc, void *pParametr):
			CUniOperationC( pProc, pParametr )
		{
			_sEvent.Create( false, false );
		}

		~CUniOperationCS()
		{
			_sEvent.Delete();
		}

		virtual void Do()
		{
			if ( _pProc != nullptr )
				_pProc( _pParametr );

			if ( --_sCounter <= 0 )
				_sEvent.Set();
		}

		bool Sync(uint uTime = -1)
		{
			return _sEvent.Wait( uTime );
		}
	};

//-------------------------------------------------------------------

}	// CoreSystems
}	// Engine

#endif	// _UX_THREAD_OPERATION_INTERFACE_H